package com.qyy.www_chatroom.component;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

//通过这个类来记录当前用户在线状态，维护了()
//此处的哈希表要考虑线程安全问题，因此使用ConcurrentHashMap是很有必要的。
//此处是我们自己写了一个哈希表进行手动管理。我们也可以借助redis中间件什么的进行处理。方便起见。我们这样处理
@Component
public class OnlineUserManager {
    private ConcurrentHashMap<Integer, WebSocketSession> sessions = new ConcurrentHashMap<>();

    //1.用户上线，给哈希表插入键值对
    //若两个不同客户端，使用同一个账号登录，也就是多开。
    //我们这里设置如果前一个客户端登录，就不允许后面客户端再登录了（代码简单）
    //要避免多开，因为多开需要写更复杂的逻辑来处理。如果多个客户端登录，如果有人给你发消息。
    //我们需要给多个客户端同时发到消息。因此逻辑上会变得更复杂。
    public void online(int userId,WebSocketSession session){
        if(sessions.get(userId) != null){
            //说明此时用户已经在线了，那么我们就登录失败，不记录映射关系.后续就收不到任何消息
            //因为我们通过映射关系实现消息转发
            System.out.println("["+ userId + "] 已经被登陆了！");
            return;
            //这个客户端断开链接的时候，会触发offline操作。进行offline的时候
            //不能就把userId:1 WebSocketSession:session1这个信息给删了
            //删除的时候，要看一下是否是删除自己的会话。
        }
        sessions.put(userId,session);
        System.out.println("["+ userId + "] 上线！");
    }

    //2.用户下线，针对这个哈希表进行删除元素
    public void offline(int userId,WebSocketSession session){
        WebSocketSession exitSession = sessions.get(userId);
        //为了防止多开，删除键值对的时候，要看一下是否是删除自己的会话session。
        //不能把别人的删了
        if(exitSession == session){
            //如果这俩Session是同一个，才真正进行下线操作，否则就啥也不干
            sessions.remove(userId);
            System.out.println("["+ userId + "] 下线！");

        }
    }
    //3.根据userId获取到WebSocketSession
    public WebSocketSession getSession(int userId){
        return sessions.get(userId);
    }


}
